const express = require('express')
const mongoose = require('mongoose')
const router = express.Router()
const msgDB = require('../../db/msg')

// 发表留言
router.post('/publish', async (req, res) => {
  let isVisitor = false
  let userInfo = req.session.userInfo
  let nameMatch = /^[^\s]{2,8}$/
  let emailMatch = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/
  let urlMatch = /^((ht|f)tps?):\/\/([\w\-]+(\.[\w\-]+)*\/)*[\w\-]+(\.[\w\-]+)*\/?(\?([\w\-\.,@?^=%&:\/~\+#]*)+)?/;
  if(userInfo){
    // 注册用户
    let {msg, section, siteAdress} = req.body
    if(!msg.trim()){
      return res.send({
        code: 1,
        msg: '留言不能为空'
      })
    }
    
    if(!urlMatch.test(siteAdress)){
      siteAdress= ''
    }
    isVisitor = false
    // 存储至数据库
    await msgDB.create({msg, user:userInfo._id, section, siteAdress, isVisitor})
    // 返回前端
    res.send({
      code: 0,
      msg: '留言成功'
    })
  }else{
    // 访客
    let {msg, section, visitor, email, siteAdress} = req.body
    if(!msg.trim()){
      return res.send({
        code: 1,
        msg: '留言不能为空'
      })
    }
    if(!nameMatch.test(visitor)){
      return res.send({
        code: 2,
        msg: '昵称格式非法'
      })
    }
    if(!emailMatch.test(email)){
      return res.send({
        code: 3,
        msg: '邮箱格式非法'
      })
    }
    if(!urlMatch.test(siteAdress)){
      siteAdress= ''
    }
    // 存储至数据库userInfo._id
    isVisitor = true
    await msgDB.create({msg, section, visitor, email, siteAdress, isVisitor})
    // 返回前端
    res.send({
      code: 0,
      msg: '留言成功'
    })
  }
})

// 回复
router.post('/reply', async (req, res) => {
  if(!req.session.userInfo){
    return res.send({
      code: 2,
      msg: '请登录后回复'
    })
  }

   // 验证数据
  let {_id, msg, replyUserId} = req.body
  let userId = req.session.userInfo._id
  if(!_id || !msg){
    return res.send({
      code: 1,
      msg: '数据格式不正确'
    })
  }

  // 用try catch防止查找报错
  try{
    // 根据msg的id更新子留言
    if(replyUserId){
      // 如果回复的是访客（只有主留言才可能是访客），则没有id
      await msgDB.findByIdAndUpdate(_id,{
        $push:{
          children:{
            msg,
            user: userId,
            replyUser: replyUserId
          }
        }
      })
    }else{
      await msgDB.findByIdAndUpdate(_id,{
        $push:{
          children:{
            msg,
            user: userId
          }
        }
      })
    }
    
    res.send({
      code: 0,
      msg: '回复成功'
    })
  }catch(e){
    res.send({
      code: 3,
      msg: e
    })
  }
})

// 获取留言
router.post('/get', async (req, res) => {
  let {pageSize, curPage, section} = req.body

  // let data = await msgDB
  //                   .find({})                    
  //                   .sort({date: -1, isTop: 1})  // 先按时间排序，再按置顶排序
  //                   .skip(curPage * pageSize)
  //                   .limit(pageSize)
  //                   .populate("user", {pass: 0})
  //                   .populate("children.user", {pass: 0})
  //                   .populate("children.replyUser", {pass: 0})
  
  data = await msgDB
                .aggregate([
                  { $match: {section}},                // 查询条件
                  { $sort: {isTop: -1, date: -1}},    // 排序
                  { $skip: curPage * pageSize},       // 跳过多少条数据
                  { $limit: pageSize},                // 限制条数
                  { $lookup:          // user表关联
                    {
                      from: "users",                      // 去连接的表名
                      localField: "user",                 // 左表的字段名
                      foreignField: "_id",                // 去连接的表的字段名，与localField是对应关系，数据类型必须一致
                      as: "users_doc"                     // 关联数据存储，为数组格式
                    }
                  },
                  { $lookup:          // 子留言中的user表关联
                    {
                      from: "users",                      // 去连接的表名
                      localField: "children.user",        // 左表的字段名
                      foreignField: "_id",                // 去连接的表的字段名，与localField是对应关系，数据类型必须一致
                      as: "children_users_doc"            // 关联数据存储，为数组格式
                    }
                  },
                  { $lookup:          // 子留言中的replyUser表关联
                    {
                      from: "users",                      // 去连接的表名
                      localField: "children.replyUser",   // 左表的字段名
                      foreignField: "_id",                // 去连接的表的字段名，与localField是对应关系，数据类型必须一致
                      as: "children_replyusers_doc"       // 关联数据存储，为数组格式
                    }
                  },
                  {
                    $project: {      // 字段过滤
                      "users_doc.pass": 0, "users_doc.regDate": 0, "users_doc.fans": 0, "users_doc.follows": 0, "users_doc.msgPermissions": 0, "users_doc.userSignature": 0,
                      "children_users_doc.pass": 0, "children_users_doc.regDate": 0, "children_users_doc.fans": 0, "children_users_doc.follows": 0, "children_users_doc.msgPermissions": 0, "children_users_doc.userSignature": 0,
                      "children_replyusers_doc.pass": 0, "children_replyusers_doc.regDate": 0, "children_replyusers_doc.fans": 0, "children_replyusers_doc.follows": 0, "children_replyusers_doc.msgPermissions": 0, "children_replyusers_doc.userSignature": 0
                    }
                  }
                ])

  // console.log(data);

  let totalCount = 0;
  await msgDB.find({section}).countDocuments((err, result)=>{
    totalCount = result
  })

  // 返回前端
  res.send({
    code: 0,
    msg: '成功获取留言',
    data:{
      totalCount,
      list: data
    }
  })
})

// 点赞
router.post('/like', async (req, res) => {
  if(!req.session.userInfo){
    return res.send({
      code: 1,
      msg: '请登录后点赞'
    })
  }

  let {itemId, childItemId} = req.body // 留言id
  let userId = req.session.userInfo._id
  
  // try catch 异步操作，防止查找失败
  try{

    let doc
    if(childItemId){
      doc = (await msgDB.findById(itemId)).children.id(childItemId)
    }else{
      doc = await msgDB.findById(itemId)
    }
    
    // ObjectId转换为String类型
    let likes = [...doc.likes].map((item) => mongoose.Types.ObjectId(item).toString())
    let index = likes.indexOf(userId)
    // 查重
    if(index !== -1){
      likes.splice(index, 1)
    }else{
      likes.push(userId)
    }

    // 更新
    if(childItemId){
      await msgDB.updateOne(
        { _id: itemId, 'children._id': childItemId }, 
        { $set:{ 'children.$.likes': likes } }
      )
    }else{
      await msgDB.updateOne(
        { _id:itemId },
        { $set: { likes } }
      )
    }
    
    return res.send({
      code: 0,
      msg: '点赞完成'
    })
  }catch(e){
    console.log(e);
    res.send({
      code: 2,
      msg: e
    })
  }
})

// 反馈
router.post('/report', async(req, res) => {
  // type: 1违法违规，2不友善，3广告嫌疑
  let {type, id, childId} = req.body

  let doc
  if(childId){
    // 子留言
    doc = (await msgDB.findById(id)).children.id(childId)
  }else{
    // 父留言
    doc = await msgDB.findById(id)
  }

  if(!doc){
    return res.send({
      code: 1,
      msg: '留言不存在'
    })
  }

  // 数组去重
  let reports = doc.reports  
  reports.push(type)
  reports = Array.from(new Set(reports))
  
  // 更新
  try{
    if(childId){
      await msgDB.updateOne(
        { _id:id, 'children._id': childId },
        { $set:{ 'children.$.reports': reports } }
      )
    }else{
      await msgDB.updateOne(
        { _id:id },
        { $set:{ reports } }
      )
    }
    res.send({
      code: 0,
      msg: '您的反馈已收到'
    })
  }
  catch(e){
    res.send({
      code: 2,
      msg: e
    })
  }
  
})

module.exports = router